﻿// ==================================================================================================
// Copyright(C) 2018 FI Ltd. All rights reserved.
//
// SYSTEM NAME	: FI.Net Application Framework
// COMPONENT ID	: FI.Core
// COMPONENT DESC:		
//
// CREATED DATE/BY:		18 Aug 2018 / Tian Mi
//
// REVISION HISTORY:	
// DATE/BY			SR#/CS/PM#/OTHERS		DESCRIPTION OF CHANGE
// ==================================================================================================

using System;
using FI.Core.ApplicationContexts;
using System.Collections.Generic;
using FI.Core.Utilities;


namespace FI.Core
{
    /// <summary>
    /// The interface of all classes which directly hold the current <see cref="ApplicationContext"/>.
    /// </summary>
   public interface IApplicationContextAwareObject
    {
        /// <summary>
        /// Gets the current application context.
        /// </summary>
        /// <value>The current application context.</value>
       ApplicationContext ApplicationContext { get; }
    }

   /// <summary>
   /// The base class of all classes which directly hold the current <see cref="ApplicationContext"/>.
   /// </summary>
   public class ApplicationContextAwareObject : MarshalByRefObject, IApplicationContextAwareObject, IDisposable
   {
       private bool _isDisposed = false;
       /// <summary>
       /// Gets the disposable objects.
       /// </summary>
       protected IList<IDisposable> DisposableObjects { get; private set; }

       /// <summary>
       /// Initializes a new instance of the <see cref="ApplicationContextAwareObject"/> class.
       /// </summary>
       public ApplicationContextAwareObject()
       {
           this.DisposableObjects = new List<IDisposable>();
       }

       /// <summary>
       /// Adds the disposable object.
       /// </summary>
       /// <param name="value">The disposable object.</param>
       protected virtual void AddDisposableObject(object value)
       {
           Guard.ArgumentNotNull(value, "disposableObject");
           IDisposable disposable = value as IDisposable;
           if (null != value && !this.DisposableObjects.Contains(disposable))
           {
               this.DisposableObjects.Add(disposable);
           }
       }

       /// <summary>
       /// Gets the current application context.
       /// </summary>
       /// <value>The current application context.</value>
       public ApplicationContext ApplicationContext
       {
           get { return ApplicationContext.Current; }
       }

       /// <summary>
       /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
       /// </summary>
       [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1816:CallGCSuppressFinalizeCorrectly"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1063:ImplementIDisposableCorrectly")]
       public virtual void Dispose()
       {
           Dispose(true);
       }

       /// <summary>
       /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
       /// </summary>
       /// <param name="disposing"></param>
       protected virtual void Dispose(bool disposing)
       {
           if (!_isDisposed)
           {
               if (disposing)
               {
                   foreach (IDisposable disposable in this.DisposableObjects)
                   {
                       disposable.Dispose();
                   }
               }
               _isDisposed = true;
           }
       }
   }
}
